import { apiClient } from './client'
import {
  Plugin,
  PluginVersion,
  PluginStats,
  PluginFilters,
  PaginatedResponse,
  PluginPaginatedResponse,
  ApiResponse
} from '@/types/api'

export class PluginService {
  // Get plugins (marketplace)
  async getPlugins(filters: PluginFilters = {}): Promise<ApiResponse<PluginPaginatedResponse>> {
    const params = new URLSearchParams()
    
    Object.entries(filters).forEach(([key, value]) => {
      if (value !== undefined && value !== null && value !== '') {
        if (Array.isArray(value)) {
          value.forEach(v => params.append(key, v))
        } else {
          params.append(key, value.toString())
        }
      }
    })

    return apiClient.get(`/plugins?${params.toString()}`)
  }

  // Get plugin by ID
  async getPluginById(id: string): Promise<ApiResponse<{ plugin: Plugin }>> {
    return apiClient.get(`/plugins/${id}`)
  }

  // Get plugin versions
  async getPluginVersions(pluginId: string): Promise<ApiResponse<{ versions: PluginVersion[] }>> {
    return apiClient.get(`/plugins/${pluginId}/versions`)
  }

  // Get plugin stats
  async getPluginStats(pluginId: string): Promise<ApiResponse<{ stats: PluginStats }>> {
    return apiClient.get(`/plugins/${pluginId}/stats`)
  }

  // Search plugins
  async searchPlugins(query: string, filters: PluginFilters = {}): Promise<ApiResponse<PaginatedResponse<Plugin>>> {
    return this.getPlugins({ ...filters, search: query })
  }

  // Get featured plugins
  async getFeaturedPlugins(): Promise<ApiResponse<{ plugins: Plugin[] }>> {
    return apiClient.get('/plugins/featured')
  }

  // Get popular plugins
  async getPopularPlugins(limit = 10): Promise<ApiResponse<{ plugins: Plugin[] }>> {
    return apiClient.get(`/plugins/popular?limit=${limit}`)
  }

  // Get recent plugins
  async getRecentPlugins(limit = 10): Promise<ApiResponse<{ plugins: Plugin[] }>> {
    return apiClient.get(`/plugins/recent?limit=${limit}`)
  }

  // Download plugin
  async downloadPlugin(pluginId: string, version?: string): Promise<ApiResponse<{ downloadUrl: string }>> {
    const url = version 
      ? `/plugins/${pluginId}/download?version=${version}`
      : `/plugins/${pluginId}/download`
    return apiClient.get(url)
  }

  // Rate plugin
  async ratePlugin(pluginId: string, rating: number, review?: string): Promise<ApiResponse> {
    return apiClient.post(`/plugins/${pluginId}/rate`, { rating, review })
  }

  // Get plugin reviews
  async getPluginReviews(pluginId: string, page = 1, limit = 10): Promise<ApiResponse<any>> {
    return apiClient.get(`/plugins/${pluginId}/reviews?page=${page}&limit=${limit}`)
  }

  // Developer plugin management
  async getMyPlugins(): Promise<ApiResponse<{ plugins: Plugin[] }>> {
    return apiClient.get('/developer/plugins')
  }

  // Create plugin
  async createPlugin(pluginData: Partial<Plugin>): Promise<ApiResponse<{ plugin: Plugin }>> {
    return apiClient.post('/developer/plugins', pluginData)
  }

  // Update plugin
  async updatePlugin(id: string, data: Partial<Plugin>): Promise<ApiResponse<{ plugin: Plugin }>> {
    return apiClient.patch(`/developer/plugins/${id}`, data)
  }

  // Delete plugin
  async deletePlugin(id: string): Promise<ApiResponse> {
    return apiClient.delete(`/developer/plugins/${id}`)
  }

  // Upload plugin file
  async uploadPluginFile(
    pluginId: string,
    file: File,
    version: string,
    changelog?: string,
    onProgress?: (progress: number) => void
  ): Promise<ApiResponse<{ version: PluginVersion }>> {
    return apiClient.upload(
      `/developer/plugins/${pluginId}/versions`,
      file,
      onProgress,
      { version, changelog }
    )
  }

  // Update plugin version
  async updatePluginVersion(
    pluginId: string,
    versionId: string,
    data: Partial<PluginVersion>
  ): Promise<ApiResponse<{ version: PluginVersion }>> {
    return apiClient.patch(`/developer/plugins/${pluginId}/versions/${versionId}`, data)
  }

  // Delete plugin version
  async deletePluginVersion(pluginId: string, versionId: string): Promise<ApiResponse> {
    return apiClient.delete(`/developer/plugins/${pluginId}/versions/${versionId}`)
  }

  // Get plugin analytics
  async getPluginAnalytics(pluginId: string, period = '30d'): Promise<ApiResponse<any>> {
    return apiClient.get(`/developer/plugins/${pluginId}/analytics?period=${period}`)
  }

  // Get categories
  async getCategories(): Promise<ApiResponse<{ categories: string[] }>> {
    return apiClient.get('/plugins/categories')
  }

  // Get tags
  async getTags(): Promise<ApiResponse<{ tags: string[] }>> {
    return apiClient.get('/plugins/tags')
  }

  // Validate plugin manifest
  async validateManifest(manifest: any): Promise<ApiResponse<{ valid: boolean; errors?: string[] }>> {
    return apiClient.post('/developer/plugins/validate-manifest', { manifest })
  }

  // Check plugin name availability
  async checkNameAvailability(name: string): Promise<ApiResponse<{ available: boolean }>> {
    return apiClient.get(`/developer/plugins/check-name?name=${encodeURIComponent(name)}`)
  }

  // Get plugin dependencies
  async getPluginDependencies(pluginId: string): Promise<ApiResponse<{ dependencies: any[] }>> {
    return apiClient.get(`/plugins/${pluginId}/dependencies`)
  }

  // Get plugins that depend on this plugin
  async getPluginDependents(pluginId: string): Promise<ApiResponse<{ dependents: Plugin[] }>> {
    return apiClient.get(`/plugins/${pluginId}/dependents`)
  }

  // Report plugin
  async reportPlugin(pluginId: string, reason: string, details?: string): Promise<ApiResponse> {
    return apiClient.post(`/plugins/${pluginId}/report`, { reason, details })
  }

  // Follow/unfollow plugin
  async followPlugin(pluginId: string): Promise<ApiResponse> {
    return apiClient.post(`/plugins/${pluginId}/follow`)
  }

  async unfollowPlugin(pluginId: string): Promise<ApiResponse> {
    return apiClient.delete(`/plugins/${pluginId}/follow`)
  }

  // Get followed plugins
  async getFollowedPlugins(): Promise<ApiResponse<{ plugins: Plugin[] }>> {
    return apiClient.get('/developer/followed-plugins')
  }
}

export const pluginService = new PluginService()
